/*
 * GeoVISTA Center (Penn State, Dept. of Geography)
 * Copyright (c), 2003-2011,  Jin Chen and Alan M. MacEachren, GeoVISTA Center, Penn State University
 * All Rights Researved.
 *
 * This library is developed and distributed for free usage,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * You can redistribute and/or modify it under the terms of the
 * Simplified BSD License
 *
 *
 *
 *
 *
 *
 *
 * Store valid axis.
 *  
    
 *  
 * @author: jin Chen
 * @date: Jun 16, 2003
 * @version: $VERSION$
 */
package edu.psu.geovista.app.plot.axis;

import edu.psu.geovista.app.pcp.toolkits.Math.JMath;
import edu.psu.geovista.classification.CategoryList;

import java.util.*;

public class AxisList {
    public static final boolean DEBUG=false;
     protected Hashtable axisList=new Hashtable();  //key: axes name; value: axis
     protected YAxis ctgAxis;  //The axis based on which the classification is made

     protected Hashtable displayIndexList=new Hashtable();



     public YAxis getAxis(int displayIndex){
        YAxis axis=(YAxis) this.displayIndexList.get(new Integer(displayIndex));
        if(axis!=null&& axis.getIndex()==displayIndex){
            return axis;
        }
        else{
            return this.getAxisSlow(displayIndex);
        }
        /*
        Iterator iter=this.iterator() ;
          while(iter.hasNext() ){
              YAxis axis=(YAxis)iter.next() ;
              if (axis.getIndex()==displayIndex){
                  return axis;
              }
          }
          return null;*/
     }
     /**
      * The method is slow but reliable
      * @param displayIndex
      * @return    YAxis with displayIndex = given one
      */
     private YAxis getAxisSlow(int displayIndex){
          Iterator iter=this.iterator() ;
          while(iter.hasNext() ){
              YAxis axis=(YAxis)iter.next() ;
              if (axis.getIndex()==displayIndex){
                  return axis;
              }
          }
          return null;
     }

    public  void updateDisplayIndexList(){
        displayIndexList.clear() ;
        Iterator iter=this.iterator() ;
          while(iter.hasNext() ){
              YAxis axis=(YAxis)iter.next() ;
              int disIndex=axis.getIndex() ;
              Integer DisIndex=new Integer(disIndex);

              if(DEBUG){
                       assert displayIndexList.containsKey(DisIndex):"display Index is NOT unique for each axis";
              }

              displayIndexList.put(DisIndex,axis);
          }
    }
    public void setAxesPaintMode(int mode){
         Iterator iter=this.iterator() ;
          while(iter.hasNext() ){
              YAxis axis=(YAxis)iter.next() ;
              axis.setPaintMode(mode);
          }
    }
     //??? need change name to getAxis(String name)
     public YAxis getAxis(String name)  {
         return (YAxis)axisList.get(name);
     }
     public void add(BasicAxis axis) {
         this.axisList.put(axis.getName() ,axis);

     }
     public Iterator iterator() {
         return this.axisList.values().iterator() ;
     }
     /**
      *
      * @return
      */
     public ArrayList getIndexSortAxisList(){
         ArrayList al=Collections.list(this.axisList.elements()) ;
         Collections.sort(al);
         return al;

     }

    public YAxis getCtgAxis() {
        return ctgAxis;
    }

    public void setCtgAxis(String name, CategoryList ctgList) {
        if (ctgAxis!=null){
            ctgAxis.setCategoryList(null);
        }
        if (name!=null){

        this.ctgAxis = this.getAxis(name);
        }

        if(ctgAxis==null){
            // 
            System.out.println("Category List is not displayed");
            return;
            //???bug
        }
        //dp{
        if (DEBUG){
            System.out.println("SET config axis ->");
            System.out.println(""+ctgAxis.getName() );
            System.out.println("min"+ctgAxis.getTickRange().getMin() );
            System.out.println("max"+ctgAxis.getTickRange().getMax() );
            System.out.println("SET config axis <-");
        }//dp}
        this.ctgAxis.setCategoryList(ctgList);
    }
     public void setCtgAxis(int index, CategoryList ctgList) {
        if (ctgAxis!=null){
            ctgAxis.setCategoryList(null);
        }
        this.ctgAxis = (YAxis)this.getAxis(index);
        this.ctgAxis.setCategoryList(ctgList);
    }
    /**
     *
     * @return name of the axes in the list
     */
    public List getAxisNameList(){
        return Collections.list(this.axisList.keys());
    }
    public ArrayList getSortAxisNameList(){
        ArrayList list=(ArrayList) getAxisNameList();
        Collections.sort(list);
        return list;
    }
    /**
     *
     * @return    mix, max of tick range among all axes in the list
     */
    public Range getListTickExtreme() {
        float[] maxs=new float[this.axisList.size()];
        float[] mins=new float[this.axisList.size()] ;

        Enumeration axes=this.axisList.elements() ;
        int i=0;
        while (axes.hasMoreElements()) {
            YAxis yAxis = (YAxis) axes.nextElement();
            Range tick=yAxis.getTickRange() ;
            maxs[i]=tick.getMax() ;
            mins[i]=tick.getMin();
            i++;
        }
        float max=JMath.getMax(maxs);
        float min=JMath.getMin(mins);
        return new Range(max,min);
    }

    public int size() {
        return this.axisList.size() ;
    }
    public Enumeration elements(){
        return this.axisList.elements() ;
    }
    public Object remove(Object key){
        return this.axisList.remove(key);
    }
    /*******************************************************************************************************
     *                support
     *******************************************************************************************************/
    /*public  static YAxis createAxis(String columnName, DefaultPlotModel dataModel,int size){

              int index=dataModel.getColumnIndexByName(columnName);
              if(index>=0){
                  return createAxis(index,dataModel,size);
              }
              else{
                  return null;
              }
    }
      /**
           *  create a axis for a dataModel's column with given index
           *  @param  index   column's index in dataModel(rawDataIndex
           */
   /*    public  static YAxis createAxis(int rawIndex, DefaultPlotModel dataModel,int size){
                 //1. label
                 String axisLabel=dataModel.getColumnName(rawIndex);


                 //2.position:
                 //Point position=AxisLayer.calculateAxisPosition(rawIndex) ;
                 Point location=new Point();

                //location.x = this.xaxis.getXByIndex((int)rawIndex) ;
                 //location.y = this.getOffset().y;
                 //System.out.println("location.x"+location.x);

              //YAxis axisy=new YAxis(axisLabel,index,AXIS_GAP,AXIS_ACTIVESIZE,position);

                 //3. data range
                 float dataMax=dataModel.getColumnMaxValue(rawIndex) ;
                 float dataMin=dataModel.getColumnMinValue(rawIndex) ;
                 Extreme dataRange=new Extreme(dataMax,dataMin);


                 YAxis axisy=new YAxis(size,location,dataRange, axisLabel, rawIndex, null);
                 float[] column=dataModel.getColumnValueAsFloat(rawIndex);
                 BoxPlot boxPlot=new BoxPlot(column);
                 axisy.setBoxplot(boxPlot);


                 //axisy.setIndex(index);
                 return axisy;

          }
*/



}
